﻿Public Interface IBussinesLogicGeneric(Of T)


    Function getDataAccesInstance() As DataAccess.DataAccessGeneric(Of T) 
    Function newQueryExpression() As BussinesLogic.WhereQueryExpression
    Function getCurrentDTO() As T

    Sub setDTO(ByVal dto As T)
     

    '    Function getNewDTO() As T 
    'Private _EntityBaseInstance As EntityBase
    'Private ReadOnly Property EntityBaseInstance() As EntityBase
    '    Get
    '        If _EntityBaseInstance Is Nothing Then
    '            _EntityBaseInstance = DirectCast(CObj(getNewDTO()), EntityBase)
    '        End If
    '        Return _EntityBaseInstance
    '    End Get

    'End Property

    'Public Class RequiredValidation
    '    Public IsValid As Boolean
    '    Public InvalidFields As IEnumerable(Of PropertiesAttributes)
    '    Public Sub New(ByVal list As IEnumerable(Of PropertiesAttributes))
    '        IsValid = Not list.Any()
    '        Me.InvalidFields = list
    '    End Sub

    'End Class
    'Public Function isValid(ByVal dto As T) As RequiredValidation
    '    Dim entBase = CType(CObj(dto), EntityBase)
    '    Return New RequiredValidation(entBase.getRequiredFields())
    'End Function

    'Public Overridable Function Add(ByVal objectEntity As T, Optional ByVal mtd As AfterAddDelegate = Nothing) As T
    '    Try
    '        If mtd IsNot Nothing Then
    '            mtd(objectEntity)
    '        End If
    '        Dim rfv = isValid(objectEntity)
    '        If rfv.IsValid Then

    '            Dim id = getDataAccesInstance.Add(objectEntity)
    '            _getCurrentDTO = Load(id)
    '            objectEntity = _getCurrentDTO
    '            Return _getCurrentDTO
    '        Else
    '            Throw New RequiredFieldsException(rfv.InvalidFields)
    '        End If

    '    Catch ex As Exception
    '        Throw ex
    '    End Try
    'End Function

    'Public Overridable Function AddCurrentDTO() As T
    '    Return Add(getCurrentDTO())
    'End Function


    'Private _getCurrentEntityPropertiesAttributes As Dictionary(Of String, PropertiesAttributes)
    'Public Function getCurrentEntityPropertiesAttributes() As Dictionary(Of String, PropertiesAttributes)
    '    If _getCurrentEntityPropertiesAttributes Is Nothing Then
    '        _getCurrentEntityPropertiesAttributes = CType(CObj(getCurrentDTO()), Entity.EntityBase).PropertiesAttributes()
    '    End If
    '    Return _getCurrentEntityPropertiesAttributes
    'End Function


    'Public Function getPrimaryKeyPropertiesAttributes() As PropertiesAttributes
    '    Return CType(CObj(getCurrentDTO()), Entity.EntityBase).getPrimaryKeyProperty
    'End Function

    'Public Function getClassAttributes() As SelfMappClassAttribute
    '    Return EntityBaseInstance.ClassAttribute()
    'End Function

    'Public Function getCascadeDeleting() As List(Of CascadeDelettingAttribute)
    '    Return EntityBaseInstance.getCascadeDeleteAttributes()
    'End Function


    'Public Function getValueFromClassName(ByVal className As String, ByVal valueTOMap As Object, ByVal propertyName As String) As Object
    '    Dim inst = ReflectionHelper.GetEntityClassInstance(className)


    '    Dim obj = BussinesLogicGenericHelper.getBussinesLogicGeneric(className)

    '    If Not GetType(EntityBase).IsAssignableFrom(inst.GetType()) Then
    '        Throw New ApplicationException(" la clase " & className & " para " & GetType(T).FullName & " no implementa EntityBase")
    '    End If

    '    Dim paramName = DirectCast(inst, EntityBase).PropertiesAttributes().Where(Function(x) x.Value.PropertyName.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)).Select(Function(x) x.Value.FieldMappingAtt.DbFieldMapp).FirstOrDefault()
    '    If paramName Is Nothing Then
    '        Throw New ApplicationException("El nombre del parámetro " & propertyName & " de la clase " & className & " para " & GetType(T).FullName & " no es encontrado")
    '    End If

    '    Dim list = obj.getListFiltered(paramName, valueTOMap)
    '    If list IsNot Nothing AndAlso list.Count > 0 Then
    '        Return CType(list(0), EntityBase).DataTextField
    '    Else
    '        Return Nothing
    '    End If
    'End Function

    'Public Function getForeingClassMappingValue(ByVal propertyItem As PropertiesAttributes) As Object
    '    Return Me.getValueFromClassName(propertyItem.ForeingClassMapping.MappingClassName, propertyItem.PropertyValue, propertyItem.ForeingClassMapping.MappingPropertyName)

    'End Function

    'Public Function getMultiInputForeingClassMappingAttribute(ByVal propertyItem As PropertiesAttributes, ByVal classInstance As T) As Object


    '    Dim thisClassInstance = DirectCast(CObj(classInstance), EntityBase)
    '    Dim otherClassInstance = DirectCast(ReflectionHelper.GetEntityClassInstance(propertyItem.MultiInputForeingClassMapping.MappingClassName), EntityBase)
    '    Dim que As New WhereQueryExpression(otherClassInstance)
    '    For Each item In propertyItem.MultiInputForeingClassMapping.MappingPropertiesName
    '        Dim thisClassProperty As PropertiesAttributes
    '        Dim otherClassProperty As PropertiesAttributes
    '        Dim v = item.Split(":"c)

    '        thisClassProperty = thisClassInstance.PropertiesAttributes().Where(Function(x) x.Value.PropertyName.Equals(v(0), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault().Value

    '        otherClassProperty = otherClassInstance.PropertiesAttributes().Where(Function(x) x.Value.PropertyName.Equals(v(1), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault().Value

    '        que.FieldName(otherClassProperty.FieldMappingAtt.DbFieldMapp, thisClassProperty.PropertyType).isEqual().ToValue(thisClassProperty.PropertyValue).And()
    '    Next


    '    Dim bl = BussinesLogicGenericHelper.getBussinesLogicGeneric(otherClassInstance.GetType().FullName)
    '    Dim l = bl.getList(que)
    '    If l IsNot Nothing AndAlso l.Count > 0 Then
    '        Return DirectCast(CObj(l(0)), EntityBase).DataTextField
    '    Else
    '        Return Nothing
    '    End If


    'End Function

    'Public Delegate Sub BeforeAddDelegate(ByVal DTOobject As T)
    'Public Delegate Sub BeforeUpdateDelegate(ByVal DTOobject As T)
    'Public Delegate Sub BeforeDeleteDelegate(ByVal DTOobject As T)
    'Public Delegate Sub AfterAddDelegate(ByVal DTOobject As T)
    'Public Delegate Sub AfterUpdateDelegate(ByVal DTOobject As T)
    'Public Delegate Sub AfterDeleteDelegate(ByVal DTOobject As T)

    'Public Overridable Sub BeforeAdd(ByVal DTOobject As T)

    'End Sub

    'Public Overridable Sub AfterAdd(ByVal DTOobject As T)

    'End Sub

    'Public Overridable Sub BeforeUpdate(ByVal DTOobject As T)

    'End Sub

    'Public Overridable Sub AfterUpdate(ByVal DTOobject As T)

    'End Sub


    'Protected Friend Sub DeleteCascade(ByVal className As String, ByVal idx As Object, ByVal paramName As String)


    '    Dim obj = BussinesLogicGenericHelper.getBussinesLogicGeneric(className)

    '    Dim list = obj.getListFiltered(paramName, idx)

    '    Dim lPK As New List(Of Object)
    '    For Each item In list
    '        Dim o = DirectCast(item, EntityBase)
    '        Dim idxs = o.getCurrentPrimaryKeyValue()
    '        obj.Delete(idxs)
    '    Next



    'End Sub


    'Private Function getDataTableStructure() As DataSet
    '    Dim key As String = "getDataTableStructure"
    '    Dim value = CacheMannager.getFromCache(Of BussinesLogicGeneric(Of T), DataSet)(key)
    '    Dim dt As New DataTable
    '    If value Is Nothing Then

    '        If EntityBaseInstance.PropertiesAttributes().Where(Function(x) x.Value.isListViewPart IsNot Nothing).Any() Then

    '            Dim partDef = EntityBaseInstance.getListPartFields()
    '            Dim mustAddID As Boolean = False

    '            mustAddID = Not partDef.Where(Function(x) x.PrimaryKeyAtt IsNot Nothing).Any()

    '            If mustAddID Then
    '                Dim dc As DataColumn
    '                dc = New DataColumn(EntityBaseInstance.getPrimaryKeyProperty().LabelAtt.Text, EntityBaseInstance.getPrimaryKeyProperty().PropertyType)
    '                dt.Columns.Add(dc)
    '            End If
    '            For Each item In partDef
    '                Dim dc As DataColumn
    '                If item.ForeingClassMapping IsNot Nothing OrElse item.MultiInputForeingClassMapping IsNot Nothing Then
    '                    If item.ForeingClassMapping IsNot Nothing Then
    '                        dc = New DataColumn(item.LabelAtt.Text, GetType(String))
    '                    Else
    '                        dc = New DataColumn(item.MultiInputForeingClassMapping.Label, GetType(String))
    '                    End If

    '                Else
    '                    dc = New DataColumn(item.LabelAtt.Text, item.PropertyType)
    '                End If
    '                dt.Columns.Add(dc)
    '            Next
    '        Else
    '            'Dim ds As New DataSet
    '            Dim partDef = EntityBaseInstance.PropertiesAttributes().Values
    '            For Each item In partDef
    '                Dim dc As DataColumn
    '                If item.ForeingClassMapping IsNot Nothing OrElse item.MultiInputForeingClassMapping IsNot Nothing Then
    '                    If item.ForeingClassMapping IsNot Nothing Then
    '                        dc = New DataColumn(item.LabelAtt.Text, GetType(String))
    '                    Else
    '                        dc = New DataColumn(item.MultiInputForeingClassMapping.Label, GetType(String))
    '                    End If

    '                Else
    '                    dc = New DataColumn(item.LabelAtt.Text, item.PropertyType)
    '                End If
    '                dt.Columns.Add(dc)
    '            Next
    '        End If
    '        Dim ds As New DataSet
    '        ds.Tables.Add(dt)
    '        CacheMannager.SetInCache(Of BussinesLogicGeneric(Of T), DataSet)(key, ds, 40)
    '        value = ds
    '    End If

    '    Return value
    'End Function

    'Public Function getListDataSource(Optional ByVal rowfrom As Integer = 0, _
    '                                  Optional ByVal rowto As Integer = 0, _
    '                                  Optional ByVal OrderBy As String = Nothing, _
    '                                  Optional ByVal query As WhereQueryExpression = Nothing) As DataSet


    '    Dim l As IEnumerable(Of T)
    '    Dim recordCount As Double = 0
    '    If query Is Nothing Then
    '        If rowto = 0 AndAlso rowfrom = rowto Then
    '            l = Me.getList()
    '            recordCount = l.Count()
    '        Else
    '            Dim prs = Me.getList(rowfrom, rowto, OrderBy)
    '            l = prs.List
    '            recordCount = prs.RecordCount
    '        End If

    '    Else
    '        If rowto = 0 AndAlso rowfrom = rowto Then
    '            l = Me.getList(query)
    '            recordCount = l.Count()
    '        Else

    '            Dim prs = Me.getList(query, rowfrom, rowto, OrderBy)
    '            l = prs.List
    '            recordCount = prs.RecordCount
    '        End If

    '    End If

    '    Dim ds As New DataSet
    '    Dim dt = getDataTableStructure().Tables(0).Clone()
    '    ds.Tables.Add(dt)
    '    If l.Any() Then

    '        If EntityBaseInstance.getListPartFields() IsNot Nothing Then



    '            Dim mustAddID As Boolean = False

    '            mustAddID = Not EntityBaseInstance.getListPartFields().Where(Function(x) x.PrimaryKeyAtt IsNot Nothing).Any()

    '            For Each linea In l.Select(Function(y) New With {.PK = DirectCast(CObj(y), EntityBase).getPrimaryKeyProperty(), .Fields = DirectCast(CObj(y), EntityBase).getListPartFields(), .TClass = y})
    '                Dim dr = dt.NewRow()
    '                Dim value As Object
    '                If mustAddID Then
    '                    value = linea.PK.PropertyValue
    '                    dr(linea.PK.LabelAtt.Text) = value

    '                End If
    '                For Each x In linea.Fields

    '                    If x.ForeingClassMapping IsNot Nothing Then
    '                        value = getForeingClassMappingValue(x)

    '                    ElseIf x.MultiInputForeingClassMapping IsNot Nothing Then
    '                        value = getMultiInputForeingClassMappingAttribute(x, linea.TClass)
    '                    Else

    '                        value = x.PropertyValue
    '                    End If
    '                    If x.MultiInputForeingClassMapping IsNot Nothing Then
    '                        dr(x.MultiInputForeingClassMapping.Label) = value
    '                    Else
    '                        dr(x.LabelAtt.Text) = value
    '                    End If

    '                Next
    '                dt.Rows.Add(dr)
    '            Next

    '        Else
    '            For Each linea In l.Select(Function(x) New With {.props = DirectCast(CObj(x), EntityBase).PropertiesAttributes().Values, .TClass = x})
    '                Dim dr = dt.NewRow()

    '                For Each x In linea.props
    '                    Dim value As Object
    '                    If x.ForeingClassMapping IsNot Nothing Then
    '                        value = Me.getForeingClassMappingValue(x)
    '                    ElseIf x.MultiInputForeingClassMapping IsNot Nothing Then
    '                        value = Me.getMultiInputForeingClassMappingAttribute(x, linea.TClass)
    '                    Else
    '                        value = x.PropertyValue
    '                    End If
    '                    dr(x.LabelAtt.Text) = value
    '                Next
    '                dt.Rows.Add(dr)
    '            Next


    '        End If
    '    End If
    '    ds.Tables.Add(New DataTable("RecordCount"))
    '    ds.Tables(1).Columns.Add(New DataColumn("RecordCount", GetType(Double)))
    '    ds.Tables(1).Rows.Add(recordCount)

    '    Return ds

    'End Function



    'Public Overridable Sub Delete(ByVal idx As Object, Optional ByVal mtd As AfterUpdateDelegate = Nothing)
    '    Try
    '        If mtd IsNot Nothing Then
    '            Dim obect As T = Me.Load(idx)
    '            mtd(obect)
    '        End If
    '        If getCascadeDeleting() IsNot Nothing Then

    '            For Each item In getCascadeDeleting()
    '                DeleteCascade(item.TableName, idx, item.ForingIDName)
    '            Next
    '        End If

    '        getDataAccesInstance().Delete(idx, getPrimaryKeyPropertiesAttributes().FieldMappingAtt.DbFieldMapp, getClassAttributes().TableName)

    '    Catch ex As Exception
    '        Throw ex
    '    End Try
    'End Sub

    'Public Sub CleanCurrentDTO()
    '    _getCurrentDTO = Nothing
    'End Sub


    'Public Function Load(ByVal PrimaryKeyValue As Object) As T
    '    Try
    '        Dim propName = getPrimaryKeyPropertiesAttributes().FieldMappingAtt.DbFieldMapp
    '        Dim propValue = PrimaryKeyValue 'getPrimaryKeyPropertiesAttributes().PropertyValue
    '        ' Dim pType As Type = getPrimaryKeyPropertiesAttributes().PropertyType
    '        'propValue = PrimaryKeyValue
    '        Dim tableName = getClassAttributes().TableName
    '        Return Load(tableName, propName, propValue)
    '    Catch ex As Exception
    '        Throw ex
    '    End Try
    'End Function

    'Public Sub LoadCurrentDTO(ByVal PrimaryKeyValue As Object)
    '    Me._getCurrentDTO = Load(PrimaryKeyValue)
    'End Sub

    'Public Function Load() As T
    '    Try

    '        Dim propName = getPrimaryKeyPropertiesAttributes().PropertyName
    '        Dim propValue = getPrimaryKeyPropertiesAttributes().PropertyValue
    '        Dim tableName = getClassAttributes().TableName
    '    Catch ex As Exception
    '        Throw ex
    '    End Try
    'End Function

    'Public Function Load(ByVal TableName As String, ByVal PrimaryKeyFieldName As String, ByVal PrimaryKeyValue As Object) As T
    '    Try
    '        Dim da = getDataAccesInstance()

    '        Return da.getOneByID(PrimaryKeyValue, PrimaryKeyFieldName, TableName)

    '    Catch ex As Exception
    '        Throw ex
    '    End Try
    'End Function



    'Public Function getEntityBaseList() As List(Of Entity.EntityBase)

    '    Return getList().Select(Function(x) DirectCast(CObj(x), Entity.EntityBase)).ToList()

    'End Function

    'Public Overridable Function UpdateCurrentDTO() As T
    '    Return Update(getCurrentDTO())
    'End Function
    'Public Overridable Function Update(ByVal obect As T, Optional ByVal mtd As AfterUpdateDelegate = Nothing) As T
    '    Try
    '        If mtd IsNot Nothing Then
    '            mtd(obect)
    '        End If
    '        Dim rfv = isValid(obect)
    '        If rfv.IsValid Then
    '            Dim da = getDataAccesInstance()
    '            Dim PrimaryKeyName = DirectCast(CObj(obect), Entity.EntityBase).getPrimaryKeyProperty().FieldMappingAtt.DbFieldMapp
    '            Dim TableName = DirectCast(CObj(obect), Entity.EntityBase).ClassAttribute.TableName
    '            da.Update(obect, PrimaryKeyName, TableName)
    '            Return obect
    '        Else
    '            Throw New RequiredFieldsException(rfv.InvalidFields)
    '        End If

    '    Catch ex As Exception
    '        Throw ex
    '    End Try

    'End Function


    'Public Function getList(ByVal qq As WhereQueryExpression) As List(Of T)
    '    Dim exResult = qq.getExpression()
    '    Return getDataAccesInstance.getList(exResult.WhereSql, exResult.Parameters)
    'End Function

    'Public Function getDataTextValueList(Optional ByVal qq As WhereQueryExpression = Nothing) As List(Of Object)
    '    Dim l As IEnumerable(Of T)

    '    If qq Is Nothing Then
    '        l = getDataAccesInstance.getList()
    '    Else
    '        Dim exResult = qq.getExpression()
    '        l = getDataAccesInstance.getList(exResult.WhereSql, exResult.Parameters)
    '    End If


    '    Dim l2 = l.Cast(Of EntityBase)().Select(Function(x) New With {.DataValueField = x.DataValueField, .DataTextField = x.DataTextField}).Cast(Of Object)()


    '    Return l2.ToList()

    'End Function

    'Public Function getDataTable() As DataTable
    '    Dim d = getDataAccesInstance().getDataTable()
    '    Return d
    'End Function


    'Public Function getList(ByVal AnonimousObject As Object) As List(Of T)
    '    Return getDataAccesInstance.getList(AnonimousObject)
    'End Function

    'Public Function getList() As List(Of T)
    '    Return getDataAccesInstance.getList()
    'End Function
    'Public Function getList(ByVal rowFrom As UInt16, ByVal rowTo As UInt32, Optional ByVal OrderByField As String = Nothing) As PagedResults(Of T)
    '    If OrderByField Is Nothing OrElse String.IsNullOrEmpty(OrderByField.Trim()) Then
    '        OrderByField = getPrimaryKeyPropertiesAttributes().FieldMappingAtt.DbFieldMapp
    '    End If
    '    Return getDataAccesInstance.getList(rowFrom, rowTo, OrderByField)
    'End Function

    'Public Function getList(ByVal qq As WhereQueryExpression, ByVal rowFrom As UInt16, ByVal rowTo As UInt32, Optional ByVal OrderByField As String = Nothing) As PagedResults(Of T)
    '    Dim exResult = qq.getExpression()

    '    Return getDataAccesInstance.getList(exResult.WhereSql, rowFrom, rowTo, OrderByField, exResult.Parameters)
    'End Function

    'Public Function getListFiltered(ByVal FieldName As String, ByVal value As Object) As List(Of T)
    '    Return getDataAccesInstance.getListFiltered(FieldName, value)
    'End Function



End Interface
